home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir37 / ushell.zip / SHELL / SH10.C < prev    next >
C/C++ Source or Header  |  1990-02-19  |  11KB  |  601 lines

  1. /* MS-DOS SHELL - Function Processing
  2.  *
  3.  * MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited
  4.  *
  5.  * This code is subject to the following copyright restrictions:
  6.  *
  7.  * 1.  Redistribution and use in source and binary forms are permitted
  8.  *     provided that the above copyright notice is duplicated in the
  9.  *     source form and the copyright notice in file sh6.c is displayed
  10.  *     on entry to the program.
  11.  *
  12.  * 2.  The sources (or parts thereof) or objects generated from the sources
  13.  *     (or parts of sources) cannot be sold under any circumstances.
  14.  *
  15.  *    $Header: sh10.c 1.1 90/01/25 13:40:54 MS_user Exp $
  16.  *
  17.  *    $Log:    sh10.c $
  18.  * Revision 1.1  90/01/25  13:40:54  MS_user
  19.  * Initial revision
  20.  * 
  21.  */
  22.  
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <stdio.h>
  26. #include <process.h>
  27. #include <dos.h>
  28. #include <signal.h>
  29. #include <errno.h>
  30. #include <setjmp.h>
  31. #include <ctype.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. #include <stdlib.h>
  35. #include <fcntl.h>
  36. #include <limits.h>
  37. #include "sh.h"
  38.  
  39. /* Function declarations */
  40.  
  41. static void    Print_Command (C_Op *);
  42. static void    Print_IO (IO_Actions *);
  43. static void    Print_Case (C_Op *);
  44. static void    Print_IString (char *, int);
  45. static void    Set_Free_ExTree (C_Op *, void (*)(char *));
  46. static void    Set_Free_Command (C_Op *, void (*)(char *));
  47. static void    Set_Free_Case (C_Op *, void (*)(char *));
  48. static void    Set_ExTree (char *);
  49. static void    Free_ExTree (char *);
  50.  
  51. static int    Print_indent;            /* Current indent level    */
  52.  
  53. /*
  54.  * print the execute tree - used for displaying functions
  55.  */
  56.  
  57. void        Print_ExTree (t)
  58. register C_Op    *t;
  59. {
  60.     char        **wp;
  61.  
  62.     if (t == (C_Op *)NULL)
  63.     return;
  64.  
  65. /* Check for start of print */
  66.  
  67.     if (t->type == TFUNC)
  68.     {
  69.     Print_indent = 0;
  70.     v1_puts (*t->words);
  71.     v1a_puts (" ()");
  72.     Print_ExTree (t->left);
  73.     return;
  74.     }
  75.  
  76. /* Otherwise, process the tree and print it */
  77.  
  78.     switch (t->type) 
  79.     {
  80.     case TPAREN:            /* ()            */
  81.     case TCOM:            /* A command process    */
  82.         Print_Command (t);
  83.         return;
  84.  
  85.     case TPIPE:            /* Pipe processing        */
  86.         Print_ExTree (t->left);
  87.         Print_IString ("|\n", 0);
  88.         Print_ExTree (t->right);
  89.         return;
  90.  
  91.     case TLIST:            /* Entries in a for statement    */
  92.         Print_ExTree (t->left);
  93.         Print_ExTree (t->right);
  94.         return;
  95.  
  96.     case TOR:            /* || and &&            */
  97.     case TAND:
  98.         Print_ExTree (t->left);
  99.  
  100.         if (t->right != (C_Op *)NULL)
  101.         {
  102.         Print_IString ((t->type == TAND) ? "&&\n" : "||\n", 0);
  103.         Print_ExTree (t->right);
  104.         }
  105.  
  106.         return;
  107.  
  108.     case TFOR:            /* First part of a for statement*/
  109.         Print_IString ("for ", 0);
  110.         v1_puts (t->str);
  111.  
  112.         if ((wp = t->words) != (char **)NULL)
  113.         {
  114.         v1_puts (" in");
  115.  
  116.         while (*wp != (char *)NULL)
  117.         {
  118.             v1_putc (SP);
  119.             v1_puts (*wp++);
  120.         }
  121.         }
  122.  
  123.         v1_putc (NL);
  124.         Print_IString ("do\n", 1);
  125.         Print_ExTree (t->left);
  126.         Print_IString ("done\n", -1);
  127.         return;
  128.  
  129.     case TWHILE:            /* WHILE and UNTIL functions    */
  130.     case TUNTIL:
  131.         Print_IString ((t->type == TWHILE) ? "while " : "until ", 1);
  132.         Print_ExTree (t->left);
  133.         Print_IString ("do\n", 0);
  134.         Print_ExTree (t->right);
  135.         Print_IString ("done\n", -1);
  136.         return;
  137.  
  138.     case TIF:            /* IF and ELSE IF functions    */
  139.     case TELIF:
  140.         if (t->type == TIF)
  141.         Print_IString ("if\n", 1);
  142.         
  143.         else
  144.         Print_IString ("elif\n", 1);
  145.         
  146.         Print_ExTree (t->left);
  147.  
  148.         Print_indent -= 1;
  149.         Print_IString ("then\n", 1);
  150.         Print_ExTree (t->right->left);
  151.  
  152.         if (t->right->right != (C_Op *)NULL)
  153.         {
  154.         Print_indent -= 1;
  155.  
  156.         if (t->right->right->type != TELIF)
  157.             Print_IString ("else\n", 1);
  158.  
  159.         Print_ExTree (t->right->right);
  160.         }
  161.  
  162.         if (t->type == TIF)
  163.         Print_IString ("fi\n", -1);
  164.  
  165.         return;
  166.  
  167.     case TCASE:            /* CASE function        */
  168.         Print_IString ("case ", 1);
  169.         v1_puts (t->str);
  170.         v1a_puts (" do");
  171.         Print_Case (t->left);
  172.         Print_IString (" esac\n", -1);
  173.         return;
  174.  
  175.     case TBRACE:            /* {} statement            */
  176.         Print_IString ("{\n", 1);
  177.         if (t->left != (C_Op *)NULL)
  178.         Print_ExTree (t->left);
  179.  
  180.         Print_IString ("}\n", -1);
  181.         return;
  182.     }
  183. }
  184.  
  185. /*
  186.  * Print a command line
  187.  */
  188.  
  189. static void    Print_Command (t)
  190. register C_Op    *t;
  191. {
  192.     char    *cp;
  193.     IO_Actions    **iopp;
  194.     char    **wp = t->words;
  195.     char    **owp = wp;
  196.  
  197.     if (t->type == TCOM) 
  198.     {
  199.     while ((cp = *wp++) != (char *)NULL)
  200.         ;
  201.  
  202.     cp = *wp;
  203.  
  204. /* strip all initial assignments not correct wrt PATH=yyy command  etc */
  205.  
  206.     if ((cp == (char *)NULL) && (t->ioact == (IO_Actions **)NULL))
  207.     {
  208.         Print_IString (null, 0);
  209.  
  210.         while (*owp != (char *)NULL)
  211.         v1a_puts (*(owp++));
  212.  
  213.         return;
  214.     }
  215.     }
  216.  
  217. /* Parenthesis ? */
  218.  
  219.     if (t->type == TPAREN)
  220.     {
  221.     Print_IString ("(\n", 1);
  222.     Print_ExTree (t->left);
  223.     Print_IString (")", -1);
  224.     }
  225.  
  226.     else
  227.     {
  228.     Print_IString (null, 0);
  229.  
  230.     while (*owp != (char *)NULL)
  231.     {
  232.         v1_puts (*owp++);
  233.  
  234.         if (*owp != (char *)NULL)
  235.         v1_putc (SP);
  236.     }
  237.     }
  238.  
  239. /* Set up anyother IO required */
  240.  
  241.     if ((iopp = t->ioact) != (IO_Actions **)NULL) 
  242.     {
  243.     while (*iopp != (IO_Actions *)NULL)
  244.         Print_IO (*iopp++);
  245.     }
  246.  
  247.     v1_putc (NL);
  248. }
  249.  
  250. /*
  251.  * Print the IO re-direction
  252.  */
  253.  
  254. static void        Print_IO (iop)
  255. register IO_Actions    *iop;
  256. {
  257.     int        unit = iop->io_unit;
  258.     static char    *cunit = " x";
  259.  
  260.     if (unit == IODEFAULT)    /* take default */
  261.     unit = (iop->io_flag & (IOREAD | IOHERE)) ? STDIN_FILENO
  262.                           : STDOUT_FILENO;
  263.  
  264. /* Output unit number */
  265.  
  266.     cunit[1] = (char)(unit + '0');
  267.     v1_puts (cunit);
  268.  
  269.     switch (iop->io_flag) 
  270.     {
  271.     case IOHERE:
  272.     case IOHERE | IOXHERE:
  273.         v1_putc ('<');
  274.  
  275.     case IOREAD:
  276.         v1_putc ('<');
  277.         break;
  278.  
  279.     case IOWRITE | IOCAT:
  280.         v1_putc ('>');
  281.  
  282.     case IOWRITE:
  283.         v1_putc ('>');
  284.         break;
  285.  
  286.     case IODUP:
  287.         v1_puts (">&");
  288.         v1_putc (*iop->io_name);
  289.         return;
  290.     }
  291.  
  292.     v1_puts (iop->io_name);
  293. }
  294.  
  295. /*
  296.  * Print out the contents of a case statement
  297.  */
  298.  
  299. static void    Print_Case (t)
  300. C_Op        *t;
  301. {
  302.     register C_Op    *t1;
  303.     register char    **wp;
  304.  
  305.     if (t == (C_Op *)NULL)
  306.     return;
  307.  
  308. /* type - TLIST - go down the left tree first and then processes this level */
  309.  
  310.     if (t->type == TLIST) 
  311.     {
  312.     Print_Case (t->left);
  313.     t1 = t->right;
  314.     }
  315.     
  316.     else
  317.     t1 = t;
  318.  
  319. /* Output the conditions */
  320.  
  321.     Print_IString (null, 0);
  322.  
  323.     for (wp = t1->words; *wp != (char *)NULL;)
  324.     {
  325.     v1_puts (*(wp++));
  326.  
  327.     if (*wp != (char *)NULL)
  328.         v1_puts (" | ");
  329.     }
  330.  
  331.     v1a_puts (" )");
  332.     Print_indent += 1;
  333.  
  334. /* Output the commands */
  335.  
  336.     Print_ExTree (t1->left);
  337.     Print_IString (";;\n", -1);
  338. }
  339.  
  340. /*
  341.  * Print an indented string
  342.  */
  343.  
  344. static void    Print_IString (cp, indent)
  345. char        *cp;
  346. int        indent;
  347. {
  348.     int        i;
  349.  
  350.     if (indent < 0)
  351.     Print_indent += indent;
  352.  
  353.     for (i = 0; i < (Print_indent / 2); i++)
  354.     v1_putc ('\t');
  355.  
  356.     if (Print_indent % 2)
  357.     v1_puts ("    ");
  358.     
  359.     v1_puts (cp);
  360.  
  361.     if (indent > 0)
  362.     Print_indent += indent;
  363. }
  364.  
  365. /*
  366.  * Look up a function in the save tree
  367.  */
  368.  
  369. Fun_Ops        *Fun_Search (name)
  370. char        *name;
  371. {
  372.     Fun_Ops    *fp;
  373.  
  374.     for (fp = fun_list; fp != (Fun_Ops *)NULL; fp = fp->next)
  375.     {
  376.     if (strcmp (*(fp->tree->words), name) == 0)
  377.         return fp;
  378.     }
  379.  
  380.     return (Fun_Ops *)NULL;
  381. }
  382.  
  383. /*
  384.  * Save or delete a function tree
  385.  */
  386.  
  387. void    Save_Function (t, delete_only)
  388. C_Op    *t;
  389. bool    delete_only;            /* True - delete        */
  390. {
  391.     char        *name = *t->words;
  392.     register Fun_Ops    *fp = Fun_Search (name);
  393.     Fun_Ops        *p_fp = (Fun_Ops *)NULL;
  394.  
  395. /* Find the entry */
  396.  
  397.     for (fp = fun_list; (fp != (Fun_Ops *)NULL) &&
  398.             (strcmp (*(fp->tree->words), name) != 0);
  399.             p_fp = fp, fp = fp->next);
  400.  
  401. /* If it already exists, free the tree and delete the entry */
  402.  
  403.     if (fp != (Fun_Ops *)NULL)
  404.     {
  405.     Set_Free_ExTree (fp->tree, Free_ExTree);
  406.  
  407.     if (p_fp == (Fun_Ops *)NULL)
  408.         fun_list = fp->next;
  409.  
  410.     else
  411.         p_fp->next = fp->next;
  412.  
  413.     DELETE (fp);
  414.     }
  415.  
  416. /* If delete only - exit */
  417.  
  418.     if (delete_only)
  419.     return;
  420.  
  421. /* Create new entry */
  422.  
  423.     if ((fp = (Fun_Ops *)space (sizeof (Fun_Ops))) == (Fun_Ops *)NULL)
  424.     return;
  425.  
  426.     setarea ((char *)fp, 0);
  427.     Set_Free_ExTree (t, Set_ExTree);
  428.  
  429.     fp->tree = t;
  430.     fp->next = fun_list;
  431.     fun_list = fp;
  432. }
  433.  
  434. /*
  435.  * Set ExTree areas to zero function
  436.  */
  437.  
  438. static void    Set_ExTree (s)
  439. char        *s;
  440. {
  441.     setarea (s, 0);
  442. }
  443.  
  444. /*
  445.  * Free the ExTree function
  446.  */
  447.  
  448. static void    Free_ExTree (s)
  449. char        *s;
  450. {
  451.     DELETE (s);
  452. }
  453.  
  454. /*
  455.  * Set/Free function tree area by recursively processing of tree
  456.  */
  457.  
  458. static void    Set_Free_ExTree (t, func)
  459. C_Op        *t;
  460. void        (*func)(char *);
  461. {
  462.     char        **wp;
  463.  
  464.     if (t == (C_Op *)NULL)
  465.     return;
  466.  
  467. /* Check for start of print */
  468.  
  469.     if (t->type == TFUNC)
  470.     {
  471.     (*func)(*t->words);
  472.     (*func)((char *)t->words);
  473.     Set_Free_ExTree (t->left, func);
  474.     }
  475.  
  476. /* Otherwise, process the tree and print it */
  477.  
  478.     switch (t->type) 
  479.     {
  480.     case TPAREN:            /* ()            */
  481.     case TCOM:            /* A command process    */
  482.         Set_Free_Command (t, func);
  483.         break;
  484.  
  485.     case TPIPE:            /* Pipe processing        */
  486.     case TLIST:            /* Entries in a for statement    */
  487.     case TOR:            /* || and &&            */
  488.     case TAND:
  489.     case TWHILE:            /* WHILE and UNTIL functions    */
  490.     case TUNTIL:
  491.         Set_Free_ExTree (t->left, func);
  492.         Set_Free_ExTree (t->right, func);
  493.         break;
  494.  
  495.     case TFOR:            /* First part of a for statement*/
  496.         (*func)(t->str);
  497.  
  498.         if ((wp = t->words) != (char **)NULL)
  499.         {
  500.         while (*wp != (char *)NULL)
  501.             (*func) (*wp++);
  502.  
  503.         (*func)((char *)t->words);
  504.         }
  505.  
  506.         Set_Free_ExTree (t->left, func);
  507.         break;
  508.  
  509.     case TIF:            /* IF and ELSE IF functions    */
  510.     case TELIF:
  511.         Set_Free_ExTree (t->right->left, func);
  512.         Set_Free_ExTree (t->right->right, func);
  513.         (*func)((char *)t->right);
  514.  
  515.     case TBRACE:            /* {} statement            */
  516.         Set_Free_ExTree (t->left, func);
  517.         break;
  518.  
  519.     case TCASE:            /* CASE function        */
  520.         (*func)(t->str);
  521.         Set_Free_Case (t->left, func);
  522.         break;
  523.     }
  524.  
  525.     (*func)((char *)t);
  526. }
  527.  
  528. /*
  529.  * Set/Free a command line
  530.  */
  531.  
  532. static void    Set_Free_Command (t, func)
  533. C_Op        *t;
  534. void        (*func)(char *);
  535. {
  536.     IO_Actions    **iopp;
  537.     char    **wp = t->words;
  538.  
  539. /* Parenthesis ? */
  540.  
  541.     if (t->type == TPAREN)
  542.     Set_Free_ExTree (t->left, func);
  543.  
  544.     else
  545.     {
  546.     while (*wp != (char *)NULL)
  547.         (*func)(*wp++);
  548.  
  549.     (*func) ((char *)t->words);
  550.     }
  551.  
  552. /* Process up any IO required */
  553.  
  554.     if ((iopp = t->ioact) != (IO_Actions **)NULL) 
  555.     {
  556.     while (*iopp != (IO_Actions *)NULL)
  557.     {
  558.         (*func)((char *)(*iopp)->io_name);
  559.         (*func)((char *)*iopp);
  560.         iopp++;
  561.     }
  562.  
  563.     (*func)((char *)t->ioact);
  564.     }
  565. }
  566.  
  567. /*
  568.  * Set/Free the contents of a case statement
  569.  */
  570.  
  571. static void    Set_Free_Case (t, func)
  572. C_Op        *t;
  573. void        (*func)(char *);
  574. {
  575.     register C_Op    *t1;
  576.     register char    **wp;
  577.  
  578.     if (t == (C_Op *)NULL)
  579.     return;
  580.  
  581. /* type - TLIST - go down the left tree first and then processes this level */
  582.  
  583.     if (t->type == TLIST) 
  584.     {
  585.     Set_Free_Case (t->left, func);
  586.     t1 = t->right;
  587.     }
  588.     
  589.     else
  590.     t1 = t;
  591.  
  592. /* Set/Free the conditions */
  593.  
  594.     for (wp = t1->words; *wp != (char *)NULL;)
  595.     (*func)(*(wp++));
  596.  
  597.     (*func)((char *)t1->words);
  598.  
  599.     Set_Free_ExTree (t1->left, func);
  600. }
  601.